<template>
  <div class="zip-file-upload">
    <el-upload
      ref="uploadRef"
      :limit="1"
      :on-exceed="handleExceed"
      :before-upload="beforeUpload"
      :on-success="handleUploadSuccess"
      :on-error="handleUploadError"
      :on-change="handleFileChange"
      :file-list="fileList"
      :auto-upload="true"
      action="#"
      accept=".zip"
      class="zip-uploader"
    >
      <el-button type="primary" icon="Upload">选择ZIP文件</el-button>
      <template #tip>
        <div class="el-upload__tip">
          只能上传ZIP格式的压缩包文件，且文件大小不超过100MB
        </div>
      </template>
    </el-upload>
    
    <!-- 文件信息显示 -->
    <div v-if="fileInfo.filePath" class="file-info">
      <el-alert
        title="文件上传成功"
        type="success"
        :closable="false"
        show-icon
      >
        <template #default>
          <div class="file-details">
            <p><strong>文件路径：</strong>{{ fileInfo.filePath }}</p>
            <p><strong>文件大小：</strong>{{ formatFileSize(fileInfo.fileSize) }}</p>
            <p><strong>文件MD5：</strong>{{ fileInfo.fileMd5 }}</p>
          </div>
        </template>
      </el-alert>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, getCurrentInstance } from 'vue'
import request from '@/utils/request'

const { proxy } = getCurrentInstance()

const props = defineProps({
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['upload-success', 'upload-error'])

// 文件列表
const fileList = ref([])
const uploadRef = ref()

// 文件信息
const fileInfo = reactive({
  filePath: '',
  fileSize: 0,
  fileMd5: ''
})

// 上传状态
const uploading = ref(false)

// 文件选择处理
function handleFileChange(file, fileList) {
  console.log('ZIP文件选择:', file, fileList)
  console.log('文件状态:', file.status)
  console.log('原始文件:', file.raw)
  
  // 检查文件是否有效
  if (file && file.raw) {
    console.log('开始上传文件到MinIO')
    // 立即上传文件
    uploadToMinIO(file.raw)
  } else {
    console.error('文件对象无效:', file)
  }
}

// 上传到MinIO
function uploadToMinIO(file) {
  if (!file) {
    proxy.$modal.msgError('文件对象为空，无法上传')
    return
  }

  // 验证文件类型
  if (!file.name.toLowerCase().endsWith('.zip')) {
    proxy.$modal.msgError('只能上传ZIP格式的压缩包文件')
    return
  }

  // 验证文件大小
  if (file.size > 100 * 1024 * 1024) {
    proxy.$modal.msgError('文件大小不能超过100MB')
    return
  }

  uploading.value = true
  const formData = new FormData()
  formData.append('file', file)

  // 显示上传进度
  const loading = proxy.$loading({
    lock: true,
    text: '正在上传ZIP文件，请稍候...',
    spinner: 'el-icon-loading',
    background: 'rgba(0, 0, 0, 0.7)'
  })

  console.log('准备调用MinIO接口:', '/race/minio/upload')
  console.log('FormData内容:', formData)
  console.log('文件信息:', {
    name: file.name,
    size: file.size,
    type: file.type
  })
  
  // 调用MinIO上传接口
  request({
    url: '/race/minio/upload',
    method: 'post',
    data: formData,
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  }).then(response => {
    console.log('ZIP文件上传响应:', response)
    loading.close()
    uploading.value = false

    console.log('完整响应数据:', response)
    
    if (response.code === 200) {
      // 计算文件MD5
      const fileMd5 = calculateFileMD5(file)
      
      // 更新文件信息 - 修复URL路径
      fileInfo.filePath = response.url  // 直接使用response.url
      fileInfo.fileSize = file.size
      fileInfo.fileMd5 = fileMd5
      
      console.log('ZIP文件信息已填充:', fileInfo)
      
      // 触发成功事件
      emit('upload-success', {
        filePath: fileInfo.filePath,
        fileSize: fileInfo.fileSize,
        fileMd5: fileInfo.fileMd5,
        fileName: file.name
      })
      
      proxy.$modal.msgSuccess('ZIP文件上传成功')
    } else {
      proxy.$modal.msgError('ZIP文件上传失败：' + response.msg)
      emit('upload-error', response.msg)
    }
  }).catch(error => {
    console.error('ZIP文件上传失败:', error)
    loading.close()
    uploading.value = false
    proxy.$modal.msgError('ZIP文件上传失败，请重试')
    emit('upload-error', error.message)
  })
}

// 计算文件MD5值
function calculateFileMD5(file) {
  const timestamp = Date.now()
  const fileName = file.name.replace(/\.[^/.]+$/, "")
  return `${fileName}_${timestamp}_${file.size}`
}

// 格式化文件大小
function formatFileSize(bytes) {
  if (bytes === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 文件数量超出限制
function handleExceed(files, fileList) {
  proxy.$modal.msgError('只能上传一个ZIP文件!')
}

// 上传前验证
function beforeUpload(file) {
  console.log('上传前验证:', file)
  return false // 阻止自动上传，我们手动处理
}

// 上传成功回调
function handleUploadSuccess(response, file, fileList) {
  console.log('上传成功回调:', response, file)
}

// 上传失败回调
function handleUploadError(error, file, fileList) {
  console.error('上传失败回调:', error, file)
  proxy.$modal.msgError('ZIP文件上传失败!')
}

// 重置组件
function reset() {
  fileList.value = []
  fileInfo.filePath = ''
  fileInfo.fileSize = 0
  fileInfo.fileMd5 = ''
  uploading.value = false
}

// 获取文件信息
function getFileInfo() {
  return {
    filePath: fileInfo.filePath,
    fileSize: fileInfo.fileSize,
    fileMd5: fileInfo.fileMd5
  }
}

// 暴露方法给父组件
defineExpose({
  reset,
  getFileInfo
})
</script>

<style scoped>
.zip-file-upload {
  width: 100%;
}

.zip-uploader {
  width: 100%;
}

.file-info {
  margin-top: 10px;
}

.file-details {
  font-size: 14px;
  line-height: 1.5;
}

.file-details p {
  margin: 5px 0;
  word-break: break-all;
}

.el-upload__tip {
  color: #606266;
  font-size: 12px;
  margin-top: 7px;
}
</style>
